package paim.gh.model.pojos;


import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.OptimisticLockType;

import paim.wingchun.model.AField;
import paim.wingchun.model.AType;
import paim.wingchun.model.Replicable;
import paim.wingchun.model.Validacao;
import paim.wingchun.model.modelos.ErroModel;
import paim.wingchun.model.pojos.Pojo;

import paim.gh.model.Gradeavel;

@AType(rotulo = "Professor", rotuloS = "Professores")
@javax.persistence.Entity(access = AccessType.FIELD)
@org.hibernate.annotations.Entity(optimisticLock = OptimisticLockType.VERSION)
public class Professor extends Pojo implements Replicable, InterfaceTabela, Gradeavel {

    private static final long serialVersionUID = 1L;

    public Professor() {}

    @Deprecated
    public Professor(Doscente doscente) {
        this.doscente = doscente;
    }

    public Professor(Grade grade, Doscente doscente) {
        this.doscente = doscente;
        this.grade = grade;
    }

    @Validacao(nulo = ErroModel.Level.ERRO$IMPEDITIVO)
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Doscente doscente;

    @Validacao(nulo = ErroModel.Level.ERRO$IMPEDITIVO)
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false)
    private Grade grade;

    // PAIM OK nao mexer mais no mamepamento, falta verificar cascade
    // @ManyToMany(mappedBy = "professores", targetEntity = Turma.class, fetch = FetchType.LAZY)
    // @Cascade({ CascadeType.PERSIST, CascadeType.SAVE_UPDATE, CascadeType.DELETE, CascadeType.REFRESH })
    @Validacao(nulo = ErroModel.Level.ALERTA)
    @Cascade({ CascadeType.EVICT, CascadeType.REFRESH })
    @OneToMany(fetch = FetchType.LAZY)
    @JoinTable
    private List<Periodo> periodos = new ArrayList<>();

    // PAIM OK nao mexer mais no mamepamento, falta verificar cascade
    @Validacao(nulo = ErroModel.Level.NENHUM)
    /* @OrderBy("opcionalidade") */
    @Cascade({ CascadeType.SAVE_UPDATE, CascadeType.DELETE, CascadeType.DELETE_ORPHAN })
    @ManyToMany(targetEntity = Preferencia.class, fetch = FetchType.LAZY)
    @JoinTable()
    private List<Preferencia> preferencias = new ArrayList<>();

    @AField(rotulo = Rotulo$descricao)
    private transient String descricao;

    @AField(rotulo = Rotulo$nome)
    private transient String nome;

    @AField(rotulo = Rotulo$sigla)
    private transient String sigla;

    @Override
    @Transient
    public String getDescricao() {
        this.descricao = getDoscente().getDescricao();
        return this.descricao;
    }

    @Override
    @Transient
    public String getNome() {
        this.nome = getDoscente().getNome();
        return this.nome;
    }

    @Override
    @Transient
    public String getSigla() {
        this.sigla = getDoscente().getSigla();
        return this.sigla;
    }

    public Doscente getDoscente() {
        return this.doscente;
    }

    public void setDoscente(Doscente doscente) {
        this.doscente = doscente;
    }

    public List<Preferencia> getPreferencias() {
        return this.preferencias;
    }

    public void setPreferencias(List<Preferencia> preferencias) {
        this.preferencias = preferencias;
    }

    public Grade getGrade() {
        return this.grade;
    }

    public void setGrade(Grade grade) {
        this.grade = grade;
    }

    public List<Periodo> getPeriodos() {
        return this.periodos;
    }

    public void setPeriodos(List<Periodo> periodos) {
        this.periodos = periodos;
    }

    @Override
    public Professor replica() {
        Professor replica = new Professor();
        // TODO Auto-generated method stub
        return replica;
    }

    @Override
    public boolean equals(Object obj) {
        if ( !super.equals(obj) )
            return false;

        Professor other = (Professor) obj;

        if ( !equals(this.doscente, other.doscente) )
            return false;
        if ( !equals(this.grade, other.grade) )
            return false;

        return true;
    }

}
